home *** CD-ROM | disk | FTP | other *** search
- /*
- Unix SMB/Netbios implementation.
- Version 1.9.
- code to manipulate domain credentials
- Copyright (C) Andrew Tridgell 1997-1998
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "includes.h"
-
- extern int DEBUGLEVEL;
-
-
-
- /****************************************************************************
- represent a credential as a string
- ****************************************************************************/
- char *credstr(uchar *cred)
- {
- static fstring buf;
- slprintf(buf,sizeof(buf)-1,"%02X%02X%02X%02X%02X%02X%02X%02X",
- cred[0], cred[1], cred[2], cred[3],
- cred[4], cred[5], cred[6], cred[7]);
- return buf;
- }
-
-
- /****************************************************************************
- setup the session key.
- Input: 8 byte challenge block
- 8 byte server challenge block
- 16 byte md4 encrypted password
- Output:
- 8 byte session key
- ****************************************************************************/
- void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass,
- uchar session_key[8])
- {
- uint32 sum[2];
- unsigned char sum2[8];
-
- sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0);
- sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4);
-
- SIVAL(sum2,0,sum[0]);
- SIVAL(sum2,4,sum[1]);
-
- cred_hash1(session_key, sum2,(unsigned char *)pass);
-
- /* debug output */
- DEBUG(4,("cred_session_key\n"));
-
- DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data)));
- DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data)));
- DEBUG(5,(" clnt+srv : %s\n", credstr(sum2)));
- DEBUG(5,(" sess_key : %s\n", credstr(session_key)));
- }
-
-
- /****************************************************************************
- create a credential
-
- Input:
- 8 byte sesssion key
- 8 byte stored credential
- 4 byte timestamp
-
- Output:
- 8 byte credential
- ****************************************************************************/
- void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp,
- DOM_CHAL *cred)
- {
- DOM_CHAL time_cred;
-
- SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time);
- SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4));
-
- cred_hash2(cred->data, time_cred.data, session_key);
-
- /* debug output*/
- DEBUG(4,("cred_create\n"));
-
- DEBUG(5,(" sess_key : %s\n", credstr(session_key)));
- DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data)));
- DEBUG(5,(" timestamp: %lx\n" , timestamp.time));
- DEBUG(5,(" timecred : %s\n", credstr(time_cred.data)));
- DEBUG(5,(" calc_cred: %s\n", credstr(cred->data)));
- }
-
-
- /****************************************************************************
- check a supplied credential
-
- Input:
- 8 byte received credential
- 8 byte sesssion key
- 8 byte stored credential
- 4 byte timestamp
-
- Output:
- returns 1 if computed credential matches received credential
- returns 0 otherwise
- ****************************************************************************/
- int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred,
- UTIME timestamp)
- {
- DOM_CHAL cred2;
-
- cred_create(session_key, stored_cred, timestamp, &cred2);
-
- /* debug output*/
- DEBUG(4,("cred_assert\n"));
-
- DEBUG(5,(" challenge : %s\n", credstr(cred->data)));
- DEBUG(5,(" calculated: %s\n", credstr(cred2.data)));
-
- if (memcmp(cred->data, cred2.data, 8) == 0)
- {
- DEBUG(5, ("credentials check ok\n"));
- return True;
- }
- else
- {
- DEBUG(5, ("credentials check wrong\n"));
- return False;
- }
- }
-
-
- /****************************************************************************
- checks credentials; generates next step in the credential chain
- ****************************************************************************/
- BOOL clnt_deal_with_creds(uchar sess_key[8],
- DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred)
- {
- UTIME new_clnt_time;
- uint32 new_cred;
-
- DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__));
-
- /* increment client time by one second */
- new_clnt_time.time = sto_clnt_cred->timestamp.time + 1;
-
- /* check that the received server credentials are valid */
- if (!cred_assert(&(rcv_srv_cred->challenge), sess_key,
- &(sto_clnt_cred->challenge), new_clnt_time))
- {
- return False;
- }
-
- /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
- new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
- new_cred += new_clnt_time.time;
-
- /* store new seed in client credentials */
- SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
-
- DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data)));
- return True;
- }
-
-
- /****************************************************************************
- checks credentials; generates next step in the credential chain
- ****************************************************************************/
- BOOL deal_with_creds(uchar sess_key[8],
- DOM_CRED *sto_clnt_cred,
- DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred)
- {
- UTIME new_clnt_time;
- uint32 new_cred;
-
- DEBUG(5,("deal_with_creds: %d\n", __LINE__));
-
- /* check that the received client credentials are valid */
- if (!cred_assert(&(rcv_clnt_cred->challenge), sess_key,
- &(sto_clnt_cred->challenge), rcv_clnt_cred->timestamp))
- {
- return False;
- }
-
- /* increment client time by one second */
- new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1;
-
- /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */
- new_cred = IVAL(sto_clnt_cred->challenge.data, 0);
- new_cred += new_clnt_time.time;
-
- DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred));
-
- /* doesn't matter that server time is 0 */
- rtn_srv_cred->timestamp.time = 0;
-
- DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time));
-
- /* create return credentials for inclusion in the reply */
- cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time,
- &(rtn_srv_cred->challenge));
-
- DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data)));
-
- /* store new seed in client credentials */
- SIVAL(sto_clnt_cred->challenge.data, 0, new_cred);
-
- return True;
- }
-
-
-